package com.example.swimmingpool.service.course_selection;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.swimmingpool.SwimmingPoolThreadLocal;
import com.example.swimmingpool.constants.RedisConstants;
import com.example.swimmingpool.entity.course_selection.CourseSelection;
import com.example.swimmingpool.mapper.course.CourseMapper;
import com.example.swimmingpool.mapper.course_selection.CourseSelectionMapper;
import com.example.swimmingpool.qo.course_selection.CourseSelectionQo;
import com.example.swimmingpool.vo.course.CourseQueryVo;
import com.example.swimmingpool.vo.course_selection.CourseSelectionVo;
import jakarta.annotation.Resource;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.stereotype.Service;

import java.util.List;


@Service
public class CourseSelectionService {
    @Resource
    private CourseSelectionMapper courseSelectionMapper;

    @Resource
    private CourseMapper courseMapper;


    @Resource
    private Redisson redisson;

    public Boolean chooseCourse(CourseSelectionQo qo) {
        RLock lock = redisson.getLock(RedisConstants.COURSE_LOCK_KEY);
        try {
            lock.lock();

            var userId = SwimmingPoolThreadLocal.getUserId();
            var courseId = qo.getCourseId();
            var account = courseMapper.getAccount(courseId);
            var chooseFlag = courseSelectionMapper.isChooseCourse(courseId, userId) == 0;

            if (account > 0 && chooseFlag) {
                courseMapper.updateAccount(courseId);
                var courseSelection = new CourseSelection();
                courseSelection.setCourseId(courseId);
                courseSelection.setUserId(userId);
                courseSelectionMapper.insert(courseSelection);
                return true;
            }
            return false;

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return false;
    }

    public List<String> getChoosenList(){
        var userId = SwimmingPoolThreadLocal.getUserId();
        return new LambdaQueryChainWrapper<>(courseSelectionMapper)
                .select(CourseSelection::getCourseId)
                .eq(CourseSelection::getUserId, userId)
                .list()
                .stream()
                .map(o -> o.getCourseId().toString())
                .distinct()
                .toList();

    }
    public IPage<CourseQueryVo> list(CourseSelectionQo qo) {
        var courseIds = new LambdaQueryChainWrapper<>(courseSelectionMapper)
                .select(CourseSelection::getCourseId)
                .eq(CourseSelection::getUserId, qo.getUserId())
                .list()
                .stream()
                .map(CourseSelection::getCourseId)
                .distinct()
                .toList();
        IPage<CourseQueryVo> page = new Page<>(qo.getCurrent(), qo.getSize());
        return courseMapper.getCoursesToUser(page, courseIds);
    }

    public IPage<CourseSelectionVo> listAll(CourseSelectionQo qo) {
        IPage<CourseSelectionVo> page = new Page<>(qo.getCurrent(), qo.getSize());
        return courseSelectionMapper.getSelectCourses(page, qo);
    }

    public Boolean delete(CourseSelectionQo qo) {
        return courseSelectionMapper.deleteById(qo.getCourseId()) != 0;
    }


}
